package de.playmee.tasks;

import de.playmee.Weather;
import de.playmee.handler.AccountHandler;
import de.playmee.handler.ChannelHandler;
import de.playmee.handler.ChannelTrackRatingHandler;
import de.playmee.handler.DatabaseHelper;
import de.playmee.handler.MusicHandler;
import de.playmee.handler.PlaylistHandler;
import de.playmee.handler.RegionHandler;
import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;

public class PrepareHandlerTask extends AsyncTask<Void, Void, Void> {
	
	public interface PrepareHandlerListener {
		public void onMusicHandlerPrepared(MusicHandler mHandler);
		public void onChannelTrackRatingHandlerPrepared(ChannelTrackRatingHandler ctrHandler);
		public void onChannelHandlerPrepared(ChannelHandler cHandler);
		public void onRegionHandlerPrepared(RegionHandler rHandler);
		public void onPlaylistHandlerPrepared(PlaylistHandler pHandler);
		public void onAllHandlerPrepared();
	}
	
	public interface AnalyzeMusicListener {
		public void onTrackCountAnalyzed(int countOfTracksOnDevice);
		public void onTrackAnalyzed(int countOfAnalyzedTracks);
		// public void onAllTracksAnalyzed();
	}
	
	private final String TAG = "PrepareHandlerTask";
	
	private Context context;
	private AccountHandler aHandler;
	private Weather weather;
	private PrepareHandlerListener prepareHandlerListener;
	private AnalyzeMusicListener analyzeMusicListener;
	
	private DatabaseHelper dbHelper;

	public PrepareHandlerTask(Context context, AccountHandler aHandler,
			Weather weather, PrepareHandlerListener prepareHandlerListener,
			AnalyzeMusicListener analyzeMusicListener) {
		this.context = context;
		this.aHandler = aHandler;
		this.weather = weather;
		this.prepareHandlerListener = prepareHandlerListener;
		this.analyzeMusicListener = analyzeMusicListener;
		this.dbHelper = new DatabaseHelper(context);
	}

	@Override
	protected Void doInBackground(Void... params) {
		// music handler
		MusicHandler mHandler = prepareMusicHandler(aHandler);
		prepareHandlerListener.onMusicHandlerPrepared(mHandler);
		
		// channel-track-rating handler
		ChannelTrackRatingHandler ctrHandler = prepareChannelTrackRatingHandler(mHandler);
		prepareHandlerListener.onChannelTrackRatingHandlerPrepared(ctrHandler);
		
		// channel handler
		ChannelHandler cHandler = prepareChannelHandler(ctrHandler);
		prepareHandlerListener.onChannelHandlerPrepared(cHandler);
		
		// region handler
		RegionHandler rHandler = prepareRegionHandler(cHandler);
		prepareHandlerListener.onRegionHandlerPrepared(rHandler);
		
		// playlist handler
		PlaylistHandler pHandler = preparePlaylistHandler(mHandler, ctrHandler, weather);
		prepareHandlerListener.onPlaylistHandlerPrepared(pHandler);
		
		prepareHandlerListener.onAllHandlerPrepared();
		return null;
	}
	
	/**
	 * creates and prepares the music handler
	 * 
	 * @param aHandler
	 * @return MusicHandler
	 */
	private MusicHandler prepareMusicHandler(AccountHandler aHandler) {
		Log.i(TAG, "Start preparing music handler...");
		
		MusicHandler mHandler = new MusicHandler(dbHelper, context.getContentResolver(),
				context.getResources(), aHandler);
		
		mHandler.openForWriting();
		analyzeMusicListener.onTrackCountAnalyzed(mHandler.getMusicOnDeviceCount());
		mHandler.prepareTracksLocalDatabase(analyzeMusicListener);
		mHandler.prepareTracksDevice(analyzeMusicListener);
		// mHandler.close();
		
		// check if user has ratings uploaded that are not available in the locale database
		mHandler.downloadAndAddMissingRatings();
		
		Log.i(TAG, "Done preparing music handler.");
		return mHandler;
	}
	
	/**
	 * creates and prepares the channel-track-rating handler
	 * 
	 * @param mHandler
	 * @return ChannelTrackRatingHandler
	 */
	private ChannelTrackRatingHandler prepareChannelTrackRatingHandler(MusicHandler mHandler) {
		Log.i(TAG, "Start preparing channel-track-rating handler...");
		
		ChannelTrackRatingHandler ctrHandler = new ChannelTrackRatingHandler(dbHelper, mHandler);
		ctrHandler.openForWriting();
		// ctrHandler.close();
		
		Log.i(TAG, "Done creating channel-track-rating handler.");
		return ctrHandler;
	}
	
	/**
	 * creates and prepares the channel handler
	 * 
	 * @param ctrHandler
	 * @return ChannelTrackRatingHandler
	 */
	private ChannelHandler prepareChannelHandler(ChannelTrackRatingHandler ctrHandler) {
		Log.i(TAG, "Start preparing channel handler...");
		
		ChannelHandler cHandler = new ChannelHandler(dbHelper, ctrHandler);
		cHandler.openForWriting();
		cHandler.prepare();
		// cHandler.close();
		
		Log.i(TAG, "Done creating channel handler.");
		return cHandler;
	}
	
	private RegionHandler prepareRegionHandler(ChannelHandler cHandler) {
		Log.i(TAG, "Start preparing channel handler...");
		
		RegionHandler rHandler = new RegionHandler(dbHelper, cHandler);
		rHandler.openForWriting();
		// rHandler.close();
		
		Log.i(TAG, "Done creating channel handler.");
		return rHandler;
	}
	
	/**
	 * creates and prepares the playlist handler
	 * 
	 * @param mHandler
	 * @param ctrHandler
	 * @return PlaylistHandler
	 */
	private PlaylistHandler preparePlaylistHandler(MusicHandler mHandler,
			ChannelTrackRatingHandler ctrHandler, Weather weather) {
		Log.i(TAG, "Start preparing playlist handler...");
		
		PlaylistHandler pHandler = new PlaylistHandler(dbHelper, mHandler, ctrHandler, weather);
		pHandler.openForWriting();
		// pHandler.close();
		
		Log.i(TAG, "Done creating playlist handler.");
		return pHandler;
	}
}
